package de.programmerspain.rv3sf.examples;

import java.awt.Color;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A simple example that updates one or more Rainbowduino V3
 * controllers every second with a random color of the
 * java.awt.Color class.
 * 
 * Every specified command line argument will be handled as
 * a serial port name. Calling the class with:
 * 'java ColorChangerExample /dev/ttyUSB0'
 * will initialize one Rainbowduino controller whereas:
 * 'java ColorChangerExample /dev/ttyUSB0 /dev/ttyUSB1'
 * will initialize two Rainbowduino controllers and so forth.
 * 
 * @author Markus Lang (m@rkus-lang.de) | http://programmers-pain.de/ | https://code.google.com/p/rainbowduino-v3-streaming-firmware/
 */
public class ColorChangerExample extends AbstractExample {
	private static final Logger LOGGER = LoggerFactory.getLogger(ColorChangerExample.class);
	
	private List<Color> colors;
	
	/**
	 * @param args the command line arguments
	 */
	public ColorChangerExample(String[] args) {
		// construct rainbowduino instances
		super(args);
		
		// resolve static declared colors of the Color class from AWT
		LOGGER.info("the following colors will be used in this example:");
		this.colors = new ArrayList<Color>();
		for (Field field : Color.class.getDeclaredFields()) {
			if (Modifier.isStatic(field.getModifiers())
					&& Modifier.isPublic(field.getModifiers())
					&& StringUtils.isAllUpperCase(field.getName())
					&& !field.getName().equals("BLACK")) {
				try {
					// get color instance and add it to the list
					Color color = (Color) field.get(null);
					colors.add(color);
					LOGGER.info(color.toString());
				} catch (IllegalArgumentException e) {
					LOGGER.error("Unable to request color instance for static field: '" + field.getName() + "'!");
				} catch (IllegalAccessException e) {
					LOGGER.error("Unable to request color instance for static field: '" + field.getName() + "'!");
				}
			}
		}
		
		// start internal executorService instances
		this.start(1, TimeUnit.SECONDS);
	}
	
	/**
	 * update the frame contents that will be send to
	 * the rainbowduinoV3 instance(s) afterwards.
	 * 
	 * @see de.programmerspain.rv3sf.examples.AbstractExample#updateFrame()
	 */
	@Override
	protected void updateFrame() {
		// randomly select a color from the colors list
		Color color = this.colors.get((int) (Math.random() * this.colors.size()));
		LOGGER.info("switched color to: " + color.toString() + "'");
		// update the frame int array of the abstract base class
		for (int pixel = 0; pixel < this.frame.length; pixel++) {
			this.frame[pixel] = color.getRGB();
		}
	}
	
	/**
	 * @param args the command line arguments array
	 */
	public static void main(String[] args) {
		new ColorChangerExample(args);
	}
}
